package viper

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"github.com/spf13/viper"
	"github.com/zeromicro/go-zero/core/logx"
	"strings"
)

// 定义nacos配置
var (
	//远程配置中心实例
	defaultConfig *viper.Viper
	//nacosip地址
	nacosIp string
	//nacos端口
	nacosPort uint64
	//nacos配置的DataID
	nacosDataId string
	//nacos配置的group分组
	nacosGroup string
)

// ThisConf 初始化viper，读取本地配置文件（需在本地建立配置文件）
func ThisConf() *viper.Viper {
	localConfig := viper.New()
	//新建本地配置中心实例
	//指定本地配置文件
	localConfig.SetConfigFile("user-api/etc/user-api.yaml")
	//读取配置文件
	if err := localConfig.ReadInConfig(); err != nil {
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}
	//监控配置文件变化
	localConfig.WatchConfig()
	localConfig.OnConfigChange(func(in fsnotify.Event) {
		logx.Info("config host load ...")
	})
	return localConfig
}

// NacosInit 注册中心客户端配置
func NacosInit() vo.NacosClientParam {
	// 初始化viper
	localConfig := ThisConf()
	// 连接远程的配置中心实例
	defaultConfig = viper.New()
	// 配置的格式
	defaultConfig.SetConfigType("yaml")
	nacosIp = localConfig.GetString("Nacos.addr")
	nacosPort = localConfig.GetUint64("Nacos.port")
	nacosDataId = localConfig.GetString("Nacos.dataId")
	nacosGroup = localConfig.GetString("Nacos.group")
	// 连接注册中心配置
	return vo.NacosClientParam{
		// 客户端配置
		ClientConfig: &constant.ClientConfig{
			NamespaceId:         localConfig.GetString("Nacos.namespaceId"),
			TimeoutMs:           localConfig.GetUint64("Nacos.timeoutMs"),
			NotLoadCacheAtStart: localConfig.GetBool("Nacos.notLoadCacheAtStart"),
			LogDir:              localConfig.GetString("Nacos.logDir"),
			CacheDir:            localConfig.GetString("Nacos.cacheDir"),
			Password:            localConfig.GetString("Nacos.password"),
			Username:            localConfig.GetString("Nacos.username"),
			LogLevel:            localConfig.GetString("Nacos.logLevel"),
		},
		// 服务端配置
		ServerConfigs: []constant.ServerConfig{
			{IpAddr: nacosIp, Port: nacosPort, ContextPath: localConfig.GetString("Nacos.contextPath"),
				Scheme: localConfig.GetString("Nacos.scheme")},
		},
	}
}

// InitViperConfig 初始化nacos配置中心
func InitViperConfig() *viper.Viper {
	nacosClient, err := clients.NewConfigClient(NacosInit())
	if err != nil {
		panic(fmt.Errorf("nacos初始化错误: %s \n", err))
	}
	content, err := nacosClient.GetConfig(vo.ConfigParam{DataId: nacosDataId, Group: nacosGroup})
	if err != nil {
		panic(fmt.Errorf("nacos读取配置错误: %s \n", err))
	}
	err = defaultConfig.ReadConfig(strings.NewReader(content))
	if err != nil {
		panic(fmt.Errorf("Viper解析配置失败: %s \n", err))
	}
	//配置监听
	err = nacosClient.ListenConfig(vo.ConfigParam{
		DataId: nacosDataId,
		Group:  nacosGroup,
		OnChange: func(namespace, group, dataId, data string) {
			logx.Info("config changed group:" + group + ", dataId:" + dataId + ", content:" + data)
			//使用viper解析配置
			err = defaultConfig.ReadConfig(strings.NewReader(data))
			if err != nil {
				panic(fmt.Errorf("Viper解析配置失败: %s \n", err))
			}
		},
	})
	return defaultConfig
}

// GetConfig 获取配置
func GetConfig() *viper.Viper {
	if defaultConfig == nil {
		defaultConfig = InitViperConfig()
	}
	return defaultConfig
}
